<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
   <meta name="Author" content="Wilbert Dijkhof">
   <title>ConditionalFilter Avisynth Filter</title>
   <link rel="stylesheet" type="text/css" href="../../avisynth.css">
</head>
<body>
<h2>
<a NAME="ConditionalFilter"></a>ConditionalFilter
</h2>
<p><code>ConditionalFilter </code>(<var>clip testclip, clip source1, clip source2,
string filter, string operator, string value, bool ''show''</var>)
<p><code>ConditionalFilter</code> restituisce il clip <var>source1</var> quando
  si verifica la condizione costituita da ''filter+operator+value'' , in caso
  contrario restituisce <var>source2</var>. Se <var>filter</var> non &egrave;
  esplicitamente applicato ad un clip, esso sar&agrave; applicato a <var>testclip</var>.
  L' audio &egrave; preso da <var>source1</var>.
<p>Un esempio. Scegliere frames da vid_blur quando il valore medio del luma di
  un frame &egrave; &lt; 20. In caso contrario i frames saranno presi da vid .
  Aggiungendo alla fine "true" si evidenzieranno sullo schermo i valori effettivi:
<pre>vid = AviSource(&quot;file&quot;)
vid_blur = vid.Blur(1.5)
ConditionalFilter(vid, vid_blur, vid, &quot;AverageLuma()&quot;, &quot;lessthan&quot;, &quot;20&quot;)</pre>
<p>La stringa <var>filter</var> pu&ograve; essere un qualsiasi filtro interno,
  ma anche alcuni filtri predefiniti (<a href="#RuntimeFunctions">vedere sotto</a>).
  <br>
  La stringa <var>operator</var> pu&ograve; essere "equals", &quot;greaterthan&quot;
  o "lessthan". O rispettivamente "=", ">" o"&lt;" . </p>
<h2><a NAME="ScriptClip"></a>ScriptClip
</h2>
<p><code>ScriptClip </code>(<var>clip, string function, bool ''show', bool
&quot;after_frame&quot;</var>)
<p><code>ScriptClip</code> restituisce il clip elaborato dalla function applicata
  ad ogni frame. </p>
Alcuni esempi : <br>
<pre># Questo mostra le differenze tra il frame precedente ed il corrente:
clip = AviSource(&quot;c:\file.avi&quot;)
ScriptClip(clip, &quot;Subtitle(String(YDifferenceFromPrevious))&quot;)

# Questo applica ad ogni frame un blur  basato sulle differenze rispetto al precedente.
# E in pi&ugrave; mostra come vengono comunicati gli errori rilevati su alcuni frames :)
clip = AviSource(&quot;c:\file.avi&quot;)
ScriptClip(clip, &quot;Blur(YDifferenceFromPrevious/20.0)&quot;)

# Questo applica temporalsoften alle scene statiche ed un blur _variabile_ alle scene movimentate.
# Blur &egrave; ora completato correttamente. In pi&ugrave; viene assegnata una variabile - e questo giustifica il line break
che &egrave; stato inserito:
function fmin(float f1, float f2) {
&nbsp; return (f1&lt;f2) ? f1 : f2
}
clip = AviSource(&quot;c:\file.avi&quot;)
ScriptClip(clip, &quot;diff = YDifferenceToNext()&quot;+chr(13)+&quot;diff &gt; 2.5 ? Blur(fmin(diff/20,1.5)) : TemporalSoften(2,7,7,3,2)&quot;)

#Mostra il frame-number in un clip:
ScriptClip(&quot;subtitle(string(current_frame))&quot;)

#Mostra 'frame = frame-number' in un clip:
ScriptClip(&quot;&quot;&quot;subtitle(&quot;frame = &quot; + string(current_frame))&quot;&quot;&quot;)</pre>

<p>Nella v2.55 &egrave; stata aggiunta un'opzione <i><var>after_frame=true/false</var></i>
  . Questa stabilisce se lo script debba essere elaborato prima (default) o dopo
  che il frame sia stato preso dai filtri precedenti.</p>

<p>"Limitazioni": l' output dello script DEVE essere esattamente simile al clip
  trasferito a <code>ScriptClip</code> (stesso colorspace, larghezza ed altezza).
  Il clip restituito pu&ograve; avere lunghezza diversa - ma quella che vuiene
  usata &egrave; sempre la lunghezza di &quot;clip" . L'Audio di "clip" rimane
  inalterato. Usando sorgenti molto diverse (MPEG2DEC3 e AviSource) - &egrave;
  possibile incorrere in errori di colorspace . Questo &egrave; un problema conosciuto.
<h2><a NAME="FrameEvaluate"></a>FrameEvaluate
</h2>
<p><code>FrameEvaluate </code>(<var>clip clip, script function, bool "after_frame"</var>)
<p>Simile a <code>ScriptClip</code>, eccetto che l'output del filter &egrave;
  ignorato. Questo &egrave; utile per assegnare variabili, etc. I frames sono
  passati direttamente partendo dal clip fornito. <br>
  Nella v2.53 &egrave; stata aggiunta un'opzione <i><var>after_frame=true/false</var></i>
  . Questa stabilisce se lo script debba essere elaborato prima (default) o dopo
  che il frame sia stato preso dai filtri precedenti.
<h2><a name="ConditionalReader"></a>ConditionalReader</h2>
<p>Questo filtro consente di importare qualsiasi informazione dentro una variabile
  selezionabile.
<p>Vedere la pagina dedicata a <a href="conditionalreader.htm">ConditionalReader</a>
  .</p>
<h2><a NAME="RuntimeFunctions"></a>Runtime Functions
</h2>
<p>Queste sono funzioni interne che sono calcolate ad ogni frame.
<p>Queste restituiscono il valor medio dei pixel di un plane (richiedono YV12,
  ISSE): <br>
  <code>AverageLuma </code>(<var>clip</var>)<br>
  <code>AverageChromaU </code>(<var>clip</var>)<br>
  <code>AverageChromaV </code>(<var>clip</var>)
<p>Queste restituiscono un valore float compreso tra 0 e 255 del valore assoluto
  delle differenze tra 2 planes (richiedono YV12, ISSE): <br>
  <code>RGBDifference </code>(<var>clip1, clip2</var>)<br>
  <code>LumaDifference </code>(<var>clip1, clip2</var>)<br>
  <code>ChromaUDifference </code>(<var>clip1, clip2</var>)<br>
  <code>ChromaVDifference </code>(<var>clip1, clip2</var>)
<p>Usando queste funzioni viene definito un clip "implicit last" (il primo parametro
  pu&ograve; non essere specificato), sicch&egrave; il primo parametro &egrave;
  sostituito dal testclip.
<p>Questo dovrebbe essere veramente funzionale per determinare i cambi di scena:
  <br>
  <code>RGBDifferenceFromPrevious </code>(<var>clip</var>)<br>
  <code>YDifferenceFromPrevious </code>(<var>clip</var>)<br>
  <code>UDifferenceFromPrevious </code>(<var>clip</var>)<br>
  <code>VDifferenceFromPrevious </code>(<var>clip</var>)<br>
  <code>RGBDifferenceToNext </code>(<var>clip</var>)<br>
  <code>YDifferenceToNext </code>(<var>clip</var>)<br>
  <code>UDifferenceToNext </code>(<var>clip</var>)<br>
  <code>VDifferenceToNext </code>(<var>clip</var>)<br>
  &nbsp;
<pre># Questo sostituisce l'ultimo frame prima di un cambio di scena
# col primo frame dopo il cambio di scena:
ConditionalFilter(last, last, last.trim(1,0), &quot;YDifferenceToNext()&quot;, &quot;&gt;&quot;, &quot;10&quot;, true)</pre>
<h4>Altre funzioni interne:</h4>
<p><code>YPlaneMax </code>(<var>clip, float threshold</var>)<br>
  <code>UPlaneMax </code>(<var>clip, float threshold</var>)<br>
  <code>VPlaneMax </code>(<var>clip, float threshold</var>)<br>
  <code>YPlaneMin </code>(<var>clip, float threshold</var>)<br>
  <code>UPlaneMin </code>(<var>clip, float threshold</var>)<br>
  <code>VPlaneMin </code>(<var>clip, float threshold</var>)<br>
  <code>YPlaneMedian </code>(<var>clip</var>)<br>
  <code>UPlaneMedian </code>(<var>clip</var>)<br>
  <code>VPlaneMedian </code>(<var>clip</var>)<br>
  <code>YPlaneMinMaxDifference </code>(<var>clip, float threshold</var>)<br>
  <code>UPlaneMinMaxDifference </code>(<var>clip, float threshold</var>)<br>
  <tt><code>VPlaneMinMaxDifference </code></tt>(<i><var>clip, float threshold</var></i>)
<p><var>Threshold</var> &egrave; una percentuale che stabilisce quanti pixels
  sono consentiti sopra o sotto il minimo. Questa soglia &egrave; opzionale e
  vale 0 di default.
<p>Se avete capito quanto esposto sopra, potete procedere con "advanced conditional
  filtering", che vi sveler&agrave; qualcosa in pi&ugrave; sul conditional filtering.
<h2>Advanced conditional filtering: part I</h2>
<p> Per capire questa sezione &egrave; necessario conoscere alcune cose sulle
  funzionalit&agrave; di AviSynth : <br>
  Gli scripts sono esaminati dall'alto al basso, ma quando viene richiesto un
  frame, viene chiamato per primo l'ultimo filtro ed il frame procede all'ins&ugrave;
  nella catena dei filtri . Ad esempio:</p>
<pre>AviSource(&quot;myfile.avi&quot;)
ColorYUV(analyze=true)
Histogram()</pre>
Aprendo lo script in Vdub ecco quello che succede
<ul>
  <li> Quando Vdub richiede un frame, AviSynth richiede il frame ad Histogram.</li>
  <li> Histogram richiede un frame a ColorYUV,</li>
  <li> ColorYUV ad AviSource, che produce il frame e lo consegna a ColorYUV.</li>
  <li> ColorYUV elabora l'immagine e la manda ad Histogram, che la restituisce
    a Vdub.</li>
</ul>
In questo modo la catena di filtri lavora all'indietro cosa che consente ai filtri
di richiedere alla sorgente pi&ugrave; di un frame contemporaneamente.
<p>I Conditional filters tuttavia, hanno bisogno di elaborare gli scripts <i>prima</i>
  di richiedere frames ai filtri che stanno prima, perch&egrave; necessitano conoscere
  quale filtro chiamare. Altro importante problema &egrave; che solo le variabili
  definite <code>global</code><i> </i>nel conditional filter 'environment' possono
  essere usate all'esterno (e vice versa). Date un'occhiata al seguente script
<pre>v = AviSource(&quot;E:\Temp\Test3\atomic_kitten.avi&quot;).ConvertToYV12

function g(clip c)
{
&nbsp; <b>global</b> <b>w</b> = c
&nbsp; c2 = ScriptClip(c, &quot;subtitle(t)&quot;)
&nbsp; c3 = FrameEvaluate(c2, &quot;t = String(text)&quot;)
&nbsp; c4 = FrameEvaluate(c3, &quot;text = YDifferenceFromPrevious(<b>w</b>)&quot;)
&nbsp; return c4
}

g(v)</pre>
Questa catena di filtri lavora in questo modo:
<ul>
  <li> Quando Vdub richiede un frame, AviSynth lo richiede a g().</li>
  <li> g() richiede un frame ad AviSource():</li>
  <ul>
    <li> AviSynth richiede un frame al secondo FrameEvaluate.</li>
    <li> Questo secondo FrameEvaluate calcola <i>YDifferenceFromPrevious(w)</i>
      ed assegna questo valore alla variabile <i>text</i>, dopo aver richiesto
      un frame di AviSource. Dopo di ci&ograve; viene richiesto un frame al primo
      FrameEvaluate.</li>
    <li> Questo FrameEvaluate richiede un frame a ScriptClip dopo 'aver calcolato
      <i>String(text)</i> ed assignato questo valore alla variabile <i>t'.</i></li>
    <li> ScriptClip richiede un frame a ConvertToYV12() e calcola <i>Subtitle(t)</i>
      di quel frame.</li>
    <li> ConvertToYV12() richiede un frame ad AviSource().</li>
  </ul>
  <li> AviSource() produce il frame e lo manda a g(), che lo restituisce a Vdub.</li>
</ul>
Come si pu&ograve; vedere , <b>w</b> &egrave; definita come &quot;variabile globale&quot;.
In questo modo la si pu&ograve; usare successivamente nello script nel conditional
environment. Se si volessero usare le variabili <b>t</b> e <b>text</b> in una
diversa function (dentro o fuori il conditional environment),anch'esse devono
essere definite come global variables. Allora ad esempio:
<pre>v = AviSource(&quot;E:\Temp\Test3\atomic_kitten.avi&quot;).ConvertToYV12

function g(clip c)
{
&nbsp; global w = c
&nbsp; c2 = ScriptClip(c, &quot;subtitle(<b>t</b>)&quot;)
&nbsp; c3 = FrameEvaluate(c2, &quot;me()&quot;)
&nbsp; c4 = FrameEvaluate(c3, &quot;<b>global</b> <b>text</b> = YDifferenceFromPrevious(w)&quot;)
&nbsp; return c4
}

function me()
{
&nbsp; <b>global</b> <b>t</b> = String(<b>text</b>)
}

g(v)</pre>
Buona parte dello script precedente &egrave; ridondante e pu&ograve; essere eliminato.
Lo script seguente produce lo stesso output
<pre>v = AviSource(&quot;c:\clip.avi&quot;)
ScriptClip(v, &quot;Subtitle(String(YDifferenceFromPrevious))&quot;)
</pre>
In the following section some frame dependent info will be written to a
text-file.
<h2>
Advanced conditional filtering: part II</h2>
<p>Nel seguente esempio alcune informazioni che dipendono dal frame saranno scritte
  in un text-file. La prima variabile &quot;a&quot; indica se il frame &egrave;
  combed (per una certa soglia &quot;threshold&quot;). Notare che IsCombed &egrave;
  un filtro del plugin Decomb . La seconda variabile &quot;b&quot; indica se nel
  frame c'&egrave; &quot;molto&quot; movimento.</p>
<pre>global sep=&quot;.&quot;
global combedthreshold=25

function IsMoving()
{
global b = (diff &lt; 1.0) ? false : true
}

function CombingInfo(clip c)
{
file = &quot;F:\interlace.log&quot;
global clip = c
c = WriteFile(c, file, &quot;a&quot;, &quot;sep&quot;, &quot;b&quot;)
c = FrameEvaluate(c, &quot;global a = IsCombed(clip, combedthreshold)&quot;)
c = FrameEvaluate(c, &quot;IsMoving&quot;)
c = FrameEvaluate(c,&quot;global diff = 0.50*YDifferenceFromPrevious(clip) + 0.25*UDifferenceFromPrevious(clip) + 0.25*VDifferenceFromPrevious(clip)&quot;)
return c
}

v = mpeg2source(&quot;F:\From_hell\from_hell.d2v&quot;).trim(100,124)
CombingInfo(v)</pre>
<p> Nella sezione seguente considereremo un esempio di &quot;adaptive motion/resizing
  filter&quot;.</p>
<h2>
Advanced conditional filtering: part III</h2>

<p> Eccovi alcuni filtri &quot;adaptive motion/resizing&quot; apparsi nei forums.
  Questi filtri discriminano tra low, medium ed high motion presente in un clip
  (sulla base dei frames). Per fare ci&ograve;, si possono usare filtri diversi
  per diversi tipi di movimento presenti nel clip. In generale, si dovrebbe usare
  temporal smoothing nelle scene a basso movimento, spatial smoothing nelle scene
  ad alto movimento e spatio-temporal smoothing nelle scena a movimento medio.
  <br>
  Di seguito, una versione semplificata del QUANTIFIED MOTION FILTER v1.5 b1 (10/07/2003)
  di HomiE FR:</p>
<pre>----------------------------------------------------
# QUANTIFIED MOTION FILTER v1.3
# LOADING AVISYNTH PLUGINS
LoadPlugin(&quot;C:\PROGRA~1\GORDIA~1\mpeg2dec3.dll&quot;)
LoadPlugin(&quot;C:\PROGRA~1\GORDIA~1\TemporalCleaner.dll&quot;)
LoadPlugin(&quot;C:\PROGRA~1\GORDIA~1\FluxSmooth.dll&quot;)
LoadPlugin(&quot;C:\PROGRA~1\GORDIA~1\UnFilter.dll&quot;)

# LOADING QUANTIFIED MOTION FILTER SCRIPT

Import(&quot;E:\temp\QMF\qmf.avs&quot;)

# LOW MOTION FILTER FUNCTION
# -&gt; SHARP RESIZING + TEMPORAL ONLY
function Low_Motion_Filter(clip c)
{
&nbsp; c = TemporalCleaner(c, 5, 10)
&nbsp; c = LanczosResize(c, 512, 272)
&nbsp; return c
}

# MEDIUM MOTION FILTER FUNCTION
# -&gt; NEUTRAL BICUBIC RESIZING + TEMPORAL &amp; SPATIAL
function Medium_Motion_Filter(clip c)
{
&nbsp; c = FluxSmooth(c, 7, 7)
&nbsp; c = BicubicResize(c, 512, 272, 0.00, 0.50)
&nbsp; return c
}

# HIGH MOTION FILTER FUNCTION
# -&gt; SOFT RESIZING + SPATIAL ONLY
function High_Motion_Filter(clip c)
{
&nbsp; c = FluxSmooth(c, -1, 14)
&nbsp; c = UnFilter(c, -30, -30)
&nbsp; c = BilinearResize(c, 512, 272)
&nbsp; return c
}

# OPENING VIDEO SOURCE
AviSource(&quot;E:\temp\QMF\britney-I_love_rock_'n_roll.avi&quot;)
ConvertToYV12(interlaced=true)
Telecide(0)

# APPLYING ADAPTATIVE RESIZING FILTER (USING QMF)
QMF()
----------------------------------------------------

# QUANTIFIED MOTION FILTER (17/08/2003) by HomiE FR (homie.fr@wanadoo.fr)
# MOTION ESTIMATION FUNCTION
function ME()
{
&nbsp; # SETTING MOTION LEVEL ACCORDING TO AVERAGE DIFFERENCE [1]
&nbsp; <b>global motion_level</b> = (<b>diff</b> &lt; threshold_lm) ? 0 : motion_level
&nbsp; <b>global motion_level</b> = (<b>diff</b> &gt;= threshold_lm &amp;&amp; <b>diff</b> &lt;= threshold_hm) ? 1 : motion_level
&nbsp; <b>global motion_level</b> = (<b>diff</b> &gt; threshold_hm) ? 2 : motion_level
}

# QUANTIFIED MOTION FILTER FUNCTION
function QMF(clip c, float &quot;threshold_lm&quot;, float &quot;threshold_hm&quot;, bool &quot;debug&quot;)
{
&nbsp; # SETTING MOTION LEVELS THRESHOLDS [2]
&nbsp; threshold_lm = default(threshold_lm, 4.0)
&nbsp; threshold_hm = default(threshold_hm, 12.0)
&nbsp; global threshold_lm = threshold_lm
&nbsp; global threshold_hm = threshold_hm

&nbsp; # ENABLING/DISABLING DEBUG INFORMATION [3]
&nbsp; debug = default(debug, false)

&nbsp; # INITIALIZING MOTION LEVEL
&nbsp; global motion_level = 0

&nbsp; # SETTING PRESENT CLIP [4]
&nbsp; global clip = c

&nbsp; # GETTING OUTPUT RESOLUTION [5]
&nbsp; width = Width(Low_Motion_Filter(c))
&nbsp; height = Height(Low_Motion_Filter(c))
&nbsp; global c_resized = PointResize(c, width, height)

&nbsp; # APPLYING MOTION FILTER ACCORDING TO MOTION LEVEL [6]
&nbsp; c = ConditionalFilter(c, Low_Motion_Filter(c), c_resized, &quot;<b>motion_level</b>&quot;, &quot;=&quot;, &quot;0&quot;)&nbsp; # [6a]
&nbsp; c = ConditionalFilter(c, Medium_Motion_Filter(c), c, &quot;<b>motion_level</b>&quot;, &quot;=&quot;, &quot;1&quot;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # [6b]
&nbsp; c = ConditionalFilter(c, High_Motion_Filter(c), c, &quot;<b>motion_level</b>&quot;, &quot;=&quot;, &quot;2&quot;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # [6c]

&nbsp; # PRINTING DEBUG INFORMATION [7]
&nbsp; c = (debug == true) ? ScriptClip(c, &quot;Debug()&quot;) : c

&nbsp; # GETTING MOTION LEVEL THROUGH MOTION ESTIMATION [8]
&nbsp; c = FrameEvaluate(c, &quot;ME()&quot;)

&nbsp; # GETTING DIFFERENCES BETWEEN PAST/PRESENT FRAMES [9]
&nbsp; c = FrameEvaluate(c, &quot;<b>global diff</b> = 0.50*YDifferenceFromPrevious(clip) + 0.25*UDifferenceFromPrevious(clip) + 0.25*VDifferenceFromPrevious(clip)&quot;)
&nbsp; return c
}

# DEBUG INFORMATION FUNCTION
function Debug(clip c)
{
&nbsp; # PRINTING VERSION INFORMATION [10]
&nbsp; c = Subtitle(c, &quot;Quantified Motion Filter&quot;, x=20, y=30, font=&quot;lucida console&quot;, size=18, text_color=$FFFFFF)
&nbsp; c = Subtitle(c, &quot;by HomiE FR (homie.fr@wanadoo.fr)&quot;, x=20, y=45, font=&quot;lucida console&quot;, size=14, text_color=$FFFFFF)

&nbsp; # PRINTING MOTION ESTIMATION INFORMATION [11]
&nbsp; c = Subtitle(c, &quot;motion estimation&quot;, x=20, y=85, font=&quot;lucida console&quot;, size=18, text_color=$FFFFFF)
&nbsp; c = Subtitle(c, &quot;diff = &quot;+string(<b>diff</b>), x=20,y=110, font=&quot;lucida console&quot;, size=16, text_color=$FFCCCC)

&nbsp; # PRINTING QUANTIFIED MOTION FILTER INFORMATION [12]
&nbsp; c = Subtitle(c, &quot;quantified motion filter&quot;, x=20, y=135, font=&quot;lucida console&quot;, size=18, text_color=$FFFFFF)
&nbsp; c = (<b>motion_level</b> == 0) ? Subtitle(c, &quot;scene type = low motion&quot;, x=20, y=160, font=&quot;lucida console&quot;, size=16, text_color=$66FF66) : c
&nbsp; c = (<b>motion_level</b> == 1) ? Subtitle(c, &quot;scene type = medium motion&quot;, x=20, y=160, font=&quot;lucida console&quot;, size=16, text_color=$66FF66) : c
&nbsp; c = (<b>motion_level</b> == 2) ? Subtitle(c, &quot;scene type = high motion&quot;, x=20, y=160, font=&quot;lucida console&quot;, size=16, text_color=$66FF66) : c
&nbsp; return c
}
----------------------------------------------------</pre>
La catena di filtri lavora cos&igrave;:
<ul>
  <li> Quando Vdub richiede un frame, AviSynth lo richiede a QMF.</li>
  <ul>
    <li> QMF richiede un frame a FrameEvaluate [9].</li>
    <li> Fatto ci&ograve; viene elaborato lo script [9] , e la global variable
      <i>diff</i> &egrave; assegnata dopo aver richiesto un frame ad AviSource.
      FrameEvaluate [9] richiede un frame a FrameEvaluate [8].</li>
    <li> Ancor una volta viene calcolato lo script [8]:</li>
    <ul>
      <li> mentre si calcola me(), la global variable <i>motion_level</i> &egrave;
        assegnata al frame [1]</li>
    </ul>
    <li> Se debug=true, un frame &egrave; richiesto a ScriptClip [7], e in questo
      modo a Debug().</li>
    <li> Dopo di ci&ograve; (e anche quando debug &egrave; impostato a false)
      un frame &egrave; richiesto all'ultimo ConditionalFilter [6c], che richiede
      un frame a [6b], che a sua volta richiede un frame a [6a].</li>
    <ul>
      <li> Si noti che alla fine viene richiesto un frame a High_Motion_filter,
        Medium_Motion_filter, o Low_Motion_filter in funzione del valore di <i>motion_level</i>.</li>
    </ul>
  </ul>
  <li> QMF richiede un frame a Telecide, Telecide a ConvertToYV12 ed infine ConvertToYV12
    ad AviSource.</li>
  <li> AviSource produce il frame e lo manda a ConvertToYV12, etc.</li>
</ul>
<p>Alcuni dettagli sono stati omessi, ma lo script in definitiva lavora in questo
  modo.</p>
<kbd>$Date: 2004/09/26 19:49:40 $</kbd>
<form>
  <input TYPE="Button" VALUE="Indietro"
onClick="history.go(-1)">
</form>
</body>
</html>
